﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace TasksUI
{
    public partial class Synchronize : Form
    {
        public Synchronize()
        {
            InitializeComponent();
            #region Operation mode
            cbType.DisplayMember = "Description";
            cbType.ValueMember = "Name";
            TasksModel.TaskStatus ts = new TasksModel.TaskStatus();
            ts.Name = TasksModel.SynchSettings.SynchDirection.TwoWay.ToString();
            ts.Description = "Two way synchronization";
            cbType.Items.Add(ts);
            ts = new TasksModel.TaskStatus();
            ts.Name = TasksModel.SynchSettings.SynchDirection.ToExternalOnly.ToString();
            ts.Description = "Change external source only";
            cbType.Items.Add(ts);
            ts = new TasksModel.TaskStatus();
            ts.Name = TasksModel.SynchSettings.SynchDirection.FromExternalOnly.ToString();
            ts.Description = "Change local data only";
            cbType.Items.Add(ts);
            #endregion
        }

        private readonly TasksModel.TaskLibrary _tl;

        public Synchronize(TasksModel.TaskLibrary tl)
            : this()
        {
            System.Diagnostics.Debug.Assert(tl.SynchSettings != null);
            System.Diagnostics.Debug.Assert(tl.SynchSettings.IsConfigured);
            _tl = tl;
            lSourceName.Text = tl.SynchSettings.ProviderName;
            if (tl.LastSynchronized.HasValue)
                lLastDate.Text = tl.LastSynchronized.Value.ToString();
            else
                lLastDate.Text = "Never";
            bStart.Enabled = true;

            switch (tl.SynchSettings.Mode)
            {
                case TasksModel.SynchSettings.SynchDirection.TwoWay:
                    cbType.SelectedIndex = 0;
                    break;
                case TasksModel.SynchSettings.SynchDirection.ToExternalOnly:
                    cbType.SelectedIndex = 1;
                    break;
                case TasksModel.SynchSettings.SynchDirection.FromExternalOnly:
                    cbType.SelectedIndex = 2;
                    break;
            }
        }

        public static void Show(TasksModel.TaskLibrary tl)
        {
            if (tl.SynchSettings == null)
            {
                MessageBox.Show("No synchronization settings configured");
                return;
            }
            using (Synchronize s = new Synchronize(tl))
            {
                s.ShowDialog(Form.ActiveForm);
            }
        }

        private void bStart_Click(object sender, EventArgs e)
        {
            bool test = cbTest.Checked;
            progress.Value = 0;
            switch (cbType.SelectedIndex)
            {
                case 0:
                    _tl.SynchSettings.Mode = TasksModel.SynchSettings.SynchDirection.TwoWay;
                    break;
                case 1:
                    _tl.SynchSettings.Mode = TasksModel.SynchSettings.SynchDirection.ToExternalOnly;
                    break;
                case 2:
                    _tl.SynchSettings.Mode = TasksModel.SynchSettings.SynchDirection.FromExternalOnly;
                    break;
            }

            bStart.Enabled = false;
            cbType.Enabled = false;
            Application.DoEvents();
            try
            {
                Helpers.ISynchronizer h = null;
                if (_tl.SynchSettings is TasksModel.GoogleCalendarSynchSettings)
                    h = DoGoogle(test);
                if (_tl.SynchSettings is TasksModel.WebServiceSynchSettings)
                    h = DoWs(test);
                if (h == null)
                    MessageBox.Show("Connection failed");
                else
                    h.Synchronize(_tl, test,
                        delegate(object s, TasksUI.Helpers.SynchProgress p)
                        {
                            Invoke(new System.Threading.ThreadStart(delegate()
                            {
                                if (progress.Maximum != p.TotalItems)
                                    progress.Maximum = p.TotalItems;
                                progress.Value = p.CompletedItems / p.TotalItems;
                            }));
                        });
                _tl.LastSynchronized = DateTime.UtcNow;
                lLastDate.Text = DateTime.Now.ToString();
                progress.Value = progress.Maximum;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
            finally
            {
                bStart.Enabled = true;
                cbType.Enabled = true;
            }
        }

        private Helpers.ISynchronizer DoGoogle(bool test)
        {
            TasksUI.Helpers.GoogleHelper h = new TasksUI.Helpers.GoogleHelper();
            h.UseSSL = true;
            if (!h.Connect(
                ((TasksModel.GoogleCalendarSynchSettings)_tl.SynchSettings).Login,
                ((TasksModel.GoogleCalendarSynchSettings)_tl.SynchSettings).Password))
                return null;
            return h;
        }

        private Helpers.ISynchronizer DoWs(bool test)
        {
            TasksUI.Helpers.WsHelper h = new Helpers.WsHelper();
            h.Url = ((TasksModel.WebServiceSynchSettings)_tl.SynchSettings).Url;
            if (!h.Connect(null, null))
                return null;
            return h;
        }
    }
}